package com.pq.aop;

import com.pq.annotation.CacheFind;
import com.pq.utils.ObjectMapperUtil;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.Jedis;

import java.util.Arrays;

@Aspect
@Component
@Slf4j
public class CacheAOP {
    @Autowired
    private Jedis jedis;

    @Around("@annotation(cacheFind)")
    public Object around(ProceedingJoinPoint joinPoint, CacheFind cacheFind) {
        Object data = null;
        try {
            // 1.获取目标方法的类
            Class<?> targetCls = joinPoint.getTarget().getClass();
            // 2.获取目标方法对象
            MethodSignature ms = (MethodSignature) joinPoint.getSignature();
            // 3.获取注解中key属性的值
            String key = cacheFind.key();
            // 4.组合key
            String parentId = Arrays.toString(joinPoint.getArgs());
            String redisKey = key + "::" + parentId;
            // 5.判断redis缓存中是否存在key,有则从缓存中获取
            if (jedis.exists(redisKey)) {
                String json = jedis.get(redisKey);
                data = ObjectMapperUtil.toObject(json, ms.getReturnType());
                log.info("从redis缓存获取数据");
            } else {
                data = joinPoint.proceed();
                String json = ObjectMapperUtil.toJSON(data);
                if (cacheFind.seconds() > 0)
                    jedis.setex(redisKey, cacheFind.seconds(), json);
                else
                    jedis.set(redisKey, json);
                log.info("从数据库查询数据");
            }
        } catch (Throwable e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
        return data;
    }
}
